/**
 * OSAmI: Open Source Ambient Intelligence
 * Copyright (C) 2010 Bull S.A.S.
 * Contact: osami-general@osami-commons.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 */

package org.osami.gateway.display.internal.identity;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.felix.ipojo.annotations.Bind;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Instantiate;
import org.apache.felix.ipojo.annotations.Invalidate;
import org.apache.felix.ipojo.annotations.Requires;
import org.apache.felix.ipojo.annotations.Unbind;
import org.apache.felix.ipojo.annotations.Validate;
import org.osami.gateway.display.internal.uri.UriAnalyzer;
import org.osami.gateway.display.internal.uri.internal.DefaultUriAnalyzer;
import org.osami.gateway.display.internal.ServletPaths;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;

@Component
@Instantiate
public class IdentitiesServlet extends HttpServlet {

    public static final String IDENTITY = "/identity";

    /**
     * serial version UID.
     */
    private static final long serialVersionUID = -9035540141367237767L;

    @Requires
    private HttpContext context;

    @Requires
    private HttpService httpService;

    private Map<UriAnalyzer, WebOperation> operations = new HashMap<UriAnalyzer, WebOperation>();

    @Validate
    public void start() throws ServletException, NamespaceException {
        this.httpService.registerServlet(IDENTITY, this, null, this.context);
    }

    @Invalidate
    public void stop() {
        this.httpService.unregister(IDENTITY);
    }

    @Bind(aggregate = true)
    public void bindWebOperation(final WebOperation operation) {
        UriAnalyzer analyzer = new DefaultUriAnalyzer(operation.getRecognizedPattern());
        this.operations.put(analyzer, operation);
    }

    @Unbind
    public void unbindWebOperation(final WebOperation operation) {
        String pattern = operation.getRecognizedPattern();
        UriAnalyzer found = null;
        for (UriAnalyzer analyzer : this.operations.keySet()) {
            if (pattern.equals(analyzer.getPattern())) {
                found = analyzer;
            }
        }

        if (found != null) {
            this.operations.remove(found);
        }
    }

    @Override
    protected void doGet(final HttpServletRequest req,
                         final HttpServletResponse resp)
            throws ServletException, IOException {
        doGetPost(req, resp);
    }

    @Override
    protected void doPost(final HttpServletRequest req,
                          final HttpServletResponse resp)
            throws ServletException, IOException {
        doGetPost(req, resp);
    }

    private void doGetPost(final HttpServletRequest req,
                           final HttpServletResponse resp)
            throws ServletException, IOException {

        boolean executed = false;
        String path = req.getPathInfo();
        for (Map.Entry<UriAnalyzer, WebOperation> entry : this.operations.entrySet()) {
            UriAnalyzer analyzer = entry.getKey();
            Map<String, String> parameters = analyzer.analyze(path);
            if (parameters != null) {
                // That means that we got a matching pattern
                executed = true;
                entry.getValue().execute(req, resp, parameters);
            }
        }

        if (!executed) {
            printDefaultPage(resp.getWriter());
        }
    }

    private void printDefaultPage(PrintWriter writer) {
        writer.println("<html lang='en'>");

        // HTML Head
        // ---------------------------------------------------
        writer.println("<head>");
        writer.println("<title>Identity Management</title>");
        writer.println("<link href=\"/resource/css/designSensor.css\" rel=\"stylesheet\" type=\"text/css\" />");
        writer.println("</head>");

        // HTML Body
        // ---------------------------------------------------
        writer.println("<body>");

        writer.println("<h1>Mapped URIs</h1><hr/>\n");

        writer.println("<ul>");
        for (UriAnalyzer analyzer : this.operations.keySet()) {
            writer.println("<li>");
            String href = IDENTITY + analyzer.getPattern();
            if (!href.contains("{")) {
                // No template attributes, we can use the value as an URL link
                writer.println("<a href='" + href + "'>");
                writer.println(href);
                writer.println("</a>");
            } else {
                // Just print the value as is
                writer.println(href);
            }
            writer.println("</li>");
        }
        writer.println("</ul>");

        writer.println("<hr/>\n<a href=\"" + ServletPaths.INDEX + "\">Go back to main page</a>\n");
        writer.println("</body>");

        writer.println("</html>");

    }

}
